//我们保证独立完成了整个程序从分析、设计到编码的所有工作。
//本段代码编写<202131773423-罗皓博>


import javazoom.jl.decoder.JavaLayerException;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

public class MyFrame extends JFrame implements KeyListener,Runnable {

    public static int choose = 0;
    static int state = 0;
    //    用于存储所有的背景
    private List<BackGround> allBg = new ArrayList<>();
    //    用于储存当前的背景
    private BackGround nowBg = new BackGround();
    //    用于双缓存
    private Image offScreenImage = null;
    //    马里奥对象
    private Mario mario = new Mario();
    //    定义一个线程对象，用于实现马里奥的运动
    private Thread thread = new Thread(this);
    StaticValue mmp = new StaticValue();

    public MyFrame() {

//        设置窗口大小
        this.setSize(800, 600);
//        设置窗口居中显示
        this.setLocationRelativeTo(null);
//        设置窗口的可见性
        this.setVisible(true);
//        设置点击窗口的关闭键，结束程序
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        设置窗口大小不可变
        this.setResizable(false);
//        向窗口对象添加键盘监听器；
        this.addKeyListener(this);
//        设置窗口名称
        this.setTitle("超级马丽");
//        初始化图片
        mmp.init();
//        初始化马里奥
        mario = new Mario(10, 355);
//        创建全部场景
        for (int i = 1; i <= 4; i++) {
            allBg.add(new BackGround(i, i));
        }
//        将第一个场景设置为当前场景
        nowBg = allBg.get(0);
        mario.setBankGround(nowBg);
//        绘制图像
        repaint();
        thread.start();
        try {
            new Music();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (JavaLayerException e) {
            e.printStackTrace();
        }
    }

    public void paint(Graphics g) {
        if (offScreenImage == null) {
            offScreenImage = createImage(800, 600);
        }
        Graphics graphics = offScreenImage.getGraphics();
        if (state == 0) {
            graphics.drawImage(StaticValue.start, 0, 0, this);
            graphics.setColor(Color.yellow);
            graphics.setFont(new Font("仿宋", Font.BOLD, 40));
            graphics.drawString("点击S 选择人物", 270, 400);

            graphics.setColor(Color.yellow);
            graphics.setFont(new Font("仿宋", Font.BOLD, 40));
            graphics.drawString("点击E 结束游戏", 270, 300);

            graphics.setColor(Color.yellow);
            graphics.setFont(new Font("仿宋", Font.BOLD, 40));
            graphics.drawString("点击J 游戏说明", 270, 200);
        }
        if(state == 4){
            graphics.drawImage(StaticValue.start2, 0, 0, this);
            graphics.setColor(Color.YELLOW);
            graphics.setFont(new Font("仿宋", Font.BOLD, 40));
            graphics.drawString("选择你的人物", 270, 200);
            graphics.drawImage(StaticValue.jump_R, 0, 0, this);
            graphics.drawImage(StaticValue.jump_R2, 0, 0, this);
            graphics.drawString("按I，选择左边", 270, 250);
            graphics.drawString("按O，选择右边", 270, 300);
            graphics.drawString("按住C，开始游戏", 270, 500);

        }
        if (state == 1) {
            graphics.fillRect(0, 0, 800, 600);
//        绘制背景
            graphics.drawImage(nowBg.getBgImage(), 0, 0, this);
//        绘制敌人
            for (Enemy e : nowBg.getEnemyList()) {
                graphics.drawImage(e.getShow(), e.getX(), e.getY(), this);
            }
//        绘制障碍物
            for (Obstacle ob : nowBg.getObstacleList()) {
                graphics.drawImage(ob.getShow(), ob.getX(), ob.getY(), this);
            }
//        绘制城堡
            graphics.drawImage(nowBg.getTower(), 660, 350, this);
//        绘制旗杆
            graphics.drawImage(nowBg.getGan(), 500, 220, this);
//        绘制马里奥
            graphics.drawImage(mario.getShow(), mario.getX(), mario.getY(), this);
//         添加分数
            Color c = graphics.getColor();
            graphics.setColor(Color.BLACK);
            graphics.setFont(new Font("黑体", Font.BOLD, 25));
            graphics.drawString("当前的分数为: " + mario.getScore(), 300, 100);
            graphics.setColor(c);

        }
        if (state == 2) {
            System.exit(0);
        }
        if (state == 3) {
            graphics.drawImage(mmp.introduce, 0, 0, this);
            graphics.setColor(Color.black);
            graphics.setFont(new Font("仿宋", Font.BOLD, 20));
            graphics.drawString("点击左键是向左移动，点击右键向右移动，点击上键向上跳", 30, 100);

            graphics.drawString("点击C，开始游戏", 30, 300);

        }
//        将图像绘制到窗口中
        g.drawImage(offScreenImage, 0, 0, this);
    }

    public static void main(String[] args) {
        MyFrame myFrame = new MyFrame();
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    //        当键盘按下按键时使用
    @Override
    public void keyPressed(KeyEvent e) {
//        向右移动
        if (e.getKeyCode() == 39) {
            mario.rightMove();
        }
//        向左移动
        if (e.getKeyCode() == 37) {
            mario.leftMove();
        }
//        跳跃
        if (e.getKeyCode() == 38) {
            mario.jump();
        }

    }

    //        当键盘松开时按键时使用
    @Override
    public void keyReleased(KeyEvent e) {
//        向左停止
        if (e.getKeyCode() == 37) {
            mario.leftStop();
        }
//        向右停止
        if (e.getKeyCode() == 39) {
            mario.rightStop();
        }
        if (e.getKeyCode() == KeyEvent.VK_S) {
            state = 4;
        }
        if (e.getKeyCode() == KeyEvent.VK_E) {
            state = 2;
        }
        if (e.getKeyCode() == KeyEvent.VK_J) {
            state = 3;
        }
        if (e.getKeyCode() == KeyEvent.VK_B) {
            state = 4;
        }
        if (e.getKeyCode() == KeyEvent.VK_I) {
            choose = 2;
            state = 1;
        }
        if (e.getKeyCode() == KeyEvent.VK_O) {
            choose = 1;
            state = 1;
        }

    }

        @Override
        public void run () {
        while (true) {
            repaint();
            try {
                Thread.sleep(50);

                if (mario.getX() >= 775) {
                    nowBg = allBg.get(nowBg.getSort());
                    mario.setBankGround(nowBg);
                    mario.setX(10);
                    mario.setY(355);
                }
//                判断马里奥是否死亡
                if (mario.isDeath()) {
                    JOptionPane.showMessageDialog(this, "马里奥死亡");
                    System.exit(0);
                }
//                判断游戏是否结束
                if (mario.isOK()) {
                    JOptionPane.showMessageDialog(this, "恭喜你！成功通关了");
                    System.exit(0);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}